package lumis.portal.group;

import lumis.portal.PortalException;
import lumis.portal.PortalObjectAlreadyExistsException;
import lumis.portal.PortalObjectNotFoundException;
import lumis.portal.UnexpectedException;
import lumis.portal.dao.*;
import lumis.portal.dao.jdbc.ITransactionJdbc;
import lumis.util.ITransaction;
import lumis.util.JdbcUtil;

import java.util.*;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * Group DAO jdbc-based implementation.
 * 
 *
 * @version $Revision: 10458 $ $Date: 2009-06-02 15:49:09 -0300 (Tue, 02 Jun 2009) $
 * @since 4.0.0
 */
class GroupDaoJdbc
{
	public GroupConfig get(String groupId, ITransaction transaction) throws DaoException, PortalException
	{
		try
		{
			GroupConfig loadedGroup = null;
			ITransactionJdbc daoTransactionJdbc = (ITransactionJdbc) transaction;
			Connection connection = daoTransactionJdbc.getConnection();
			PreparedStatement statement = connection.prepareStatement("select * from lum_Group where groupId = ?");
			try
			{
				statement.setString(1, groupId);
				ResultSet resultSet = statement.executeQuery();
				try
				{
					if (resultSet.next())
					{
						loadedGroup = new GroupConfig();
						loadedGroup.setId(resultSet.getString("groupId"));
						loadedGroup.setAlias(resultSet.getString("alias"));
						loadedGroup.setName(resultSet.getString("name"));
						loadedGroup.setDescription(resultSet.getString("description"));
						loadedGroup.setType(resultSet.getInt("type"));
						loadedGroup.setAccessControlListId(resultSet.getString("accessControlListId"));
						loadedGroup.setChannelId(resultSet.getString("channelId"));
						loadedGroup.setGroupTypeId(resultSet.getString("groupTypeId"));
					}
				}
				finally
				{
					resultSet.close();
				}
			}
			finally
			{
				statement.close();
			}
			
			if (loadedGroup == null)
				throw new PortalObjectNotFoundException("Group id='" + groupId + "' not found");
			
			return loadedGroup;
		}
		catch (PortalException e)
		{
			throw e;
		}
		catch (Exception e)
		{
			throw new UnexpectedException(e);
		}

	}

	public void add(GroupConfig groupConfig, ITransaction transaction) throws DaoException, PortalException
	{
		try
		{
			ITransactionJdbc daoTransactionJdbc = (ITransactionJdbc) transaction;
			Connection connection = daoTransactionJdbc.getConnection();

			PreparedStatement statement = connection.prepareStatement("insert into lum_Group (groupId, alias, name, description, type, accessControlListId, channelId, origin, groupTypeId) values (?, ?, ?, ?, ?, ?, ?, ?, ?) ");

			statement.setString(1, groupConfig.getId());
			statement.setString(2, groupConfig.getAlias());
			statement.setString(3, groupConfig.getName());
			statement.setString(4, groupConfig.getDescription());
			statement.setInt(5, groupConfig.getType());
			statement.setString(6, groupConfig.getAccessControlListId());
			statement.setString(7, groupConfig.getChannelId());
			statement.setString(8, groupConfig.getOrigin());
			statement.setString(9, groupConfig.getGroupTypeId());

			try
			{
				statement.executeUpdate();
			}
			catch (Exception e)
			{
				try
				{
					if(get(groupConfig.getId(), transaction) != null)
						throw new PortalObjectAlreadyExistsException("STR_RESOURCE_ALREADY_EXISTS;" + groupConfig.getId(), e);
					else
						throw e;
				}
				catch (PortalObjectNotFoundException e1)
				{
					throw e;
				}
			}
			statement.close();
		}
		catch (PortalException e)
		{
			throw e;
		}
		catch (Exception e)
		{
			throw new UnexpectedException(e);
		}
	}

	public void update(GroupConfig groupConfig, ITransaction transaction) throws DaoException, PortalException
	{
		try
		{
			ITransactionJdbc daoTransactionJdbc = (ITransactionJdbc) transaction;
			Connection connection = daoTransactionJdbc.getConnection();

			PreparedStatement statement = connection.prepareStatement("update lum_Group set alias=?, name=?, description=?, type=?, accessControlListId=?, channelId=?, groupTypeId=? where groupId = ?");

			statement.setString(1, groupConfig.getAlias());
			statement.setString(2, groupConfig.getName());
			statement.setString(3, groupConfig.getDescription());
			statement.setInt(4, groupConfig.getType());
			statement.setString(5, groupConfig.getAccessControlListId());
			statement.setString(6, groupConfig.getChannelId());
			statement.setString(7, groupConfig.getGroupTypeId());
			statement.setString(8, groupConfig.getId());

			statement.executeUpdate();
			statement.close();
		}
		catch (PortalException e)
		{
			throw e;
		}
		catch (Exception e)
		{
			throw new UnexpectedException(e);
		}
	}

	public void delete(String groupId, ITransaction transaction) throws DaoException, PortalException
	{
		try
		{
			ITransactionJdbc daoTransactionJdbc = (ITransactionJdbc) transaction;
			Connection connection = daoTransactionJdbc.getConnection();

			PreparedStatement statement = connection.prepareStatement("delete from lum_Group where groupId = ?");
			statement.setString(1, groupId);
			statement.executeUpdate();
			statement.close();
		}
		catch (PortalException e)
		{
			throw e;
		}
		catch (Exception e)
		{
			throw new UnexpectedException(e);
		}
	}

	public Collection<String> getIds(ITransaction transaction) throws DaoException, PortalException
	{
		try
		{
			Collection<String> groupIds = new ArrayList<String>();

			ITransactionJdbc daoTransactionJdbc = (ITransactionJdbc) transaction;
			Connection connection = daoTransactionJdbc.getConnection();
			PreparedStatement statement = connection.prepareStatement("select groupId from lum_Group");
			try
			{
				ResultSet resultSet = statement.executeQuery();
				try
				{
					while (resultSet.next())
					{
						groupIds.add(resultSet.getString("groupId"));
					}					
				}
				finally
				{
					resultSet.close();					
				}
			}
			finally
			{
				statement.close();				
			}
			return groupIds;
		}
		catch (PortalException e)
		{
			throw e;
		}
		catch (Exception e)
		{
			throw new UnexpectedException(e);
		}
	}

	public Collection<String> getByChannelId(String channelId, ITransaction transaction) throws DaoException, PortalException
	{
		try
		{
			Collection<String> groups = new ArrayList<String>();

			ITransactionJdbc daoTransactionJdbc = (ITransactionJdbc) transaction;
			Connection connection = daoTransactionJdbc.getConnection();
			PreparedStatement statement = connection.prepareStatement("select groupId from lum_Group where channelId " +  ( channelId == null ? " is null " : "= ?"));

			if( channelId != null )
				statement.setString(1, channelId);
			ResultSet resultSet = statement.executeQuery();

			while (resultSet.next())
			{
				groups.add(resultSet.getString("groupId"));
			}

			resultSet.close();
			statement.close();

			return groups;
		}
		catch (PortalException e)
		{
			throw e;
		}
		catch (Exception e)
		{
			throw new UnexpectedException(e);
		}
	}
	
	public Collection<String> getByOrigin(String origin, ITransaction transaction) throws DaoException, PortalException
	{
		try
		{
			Collection<String> groups = new ArrayList<String>();

			ITransactionJdbc daoTransactionJdbc = (ITransactionJdbc) transaction;
			Connection connection = daoTransactionJdbc.getConnection();
			PreparedStatement statement = connection.prepareStatement("select groupId from lum_Group where origin  = ?");
			try
			{
				
				statement.setString(1, origin);
				ResultSet resultSet = statement.executeQuery();
				try
				{
					while (resultSet.next())
					{
						groups.add(resultSet.getString("groupId"));
					}
				}
				finally
				{
					resultSet.close();
				}
			}
			finally
			{
				statement.close();
			}

			return groups;
		}
		catch (PortalException e)
		{
			throw e;
		}
		catch (Exception e)
		{
			throw new UnexpectedException(e);
		}
	}
	
	/**
	 * Returns the identifiers of groups belonging to a group type.
	 * @param groupTypeId the group type identifier.
	 * @param transaction the transaction for persistence access.
	 * @return the group identifiers.
	 * @since 4.2.1
	 */
	public Collection<String> getByGroupTypeId(String groupTypeId, ITransaction transaction) throws DaoException, PortalException
	{
		try
		{
			ITransactionJdbc daoTransactionJdbc = (ITransactionJdbc) transaction;
			Connection connection = daoTransactionJdbc.getConnection();
			PreparedStatement statement = connection.prepareStatement("select groupId from lum_Group where groupTypeId = ?");
			try
			{
				statement.setString(1, groupTypeId);
				return JdbcUtil.fillListString(statement, "groupId");
			}
			finally
			{
				statement.close();
			}
		}
		catch (SQLException e)
		{
			throw new UnexpectedException(e);
		}
	}
}
